package com.example.demo;

import java.lang.management.ManagementFactory;

import javax.annotation.PostConstruct;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.HikariPoolMXBean;

import lombok.extern.slf4j.Slf4j;

@SpringBootApplication
public class DemoApplication implements ApplicationRunner {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

	@Override
	public void run(ApplicationArguments args) throws Exception {
		System.out.println("app runner...");
	}

}

@RestController
@Slf4j
@EnableAsync
class TestController {

	@Autowired
	AsyncService as;

	@Autowired
	DataSource ds;

	HikariPoolMXBean poolProxy;

	@PostConstruct
	void init() throws MalformedObjectNameException {
		MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
		ObjectName poolName = new ObjectName(
				"com.zaxxer.hikari:type=Pool (" + ((HikariDataSource) ds).getPoolName() + ")");
		poolProxy = JMX.newMXBeanProxy(mBeanServer, poolName, HikariPoolMXBean.class);

	}

	@GetMapping("test")
	Object test() {

//		System.out.println(ds.getClass());
		System.out.println(Thread.currentThread().getName());

		as.task1();
		
		System.out.println("test...");

		return "OK";

	}

	@Scheduled(fixedRate = 1000)
	public void HikariMonitor() {

		if (poolProxy == null) {
			log.info("Hikari not initialized,please wait...");
		} else {
			log.info("HikariPoolState = " + "Active=["
					+ String.valueOf(poolProxy.getActiveConnections() + "] " + "Idle=["
							+ String.valueOf(poolProxy.getIdleConnections() + "] " + "Wait=["
									+ poolProxy.getThreadsAwaitingConnection() + "] " + "Total=["
									+ poolProxy.getTotalConnections() + "]")));
		}

	}

}
